#include <bits/stdc++.h>
using namespace std;

#define ls  p<<1
#define rs  p<<1|1

typedef pair<int,int> P;
typedef long long int ll;
const int N=1e5+7;
const int M=1e9+7;
ll pp;
int a[N];
int n,m;

ll fp(ll n,ll pow){
	ll res=1;
	while(pow){
		if(pow&1)res=res*n%pp;
		pow>>=1;
		n=n*n%pp;
	}
	return res;
}

struct seg{
	ll val[N<<2];
	ll add[N<<2];
	ll mul[N<<2];
	bool f[N<<2];
	void init(int s,int t,int p){
		mul[p]=1;
		add[p]=0;
		f[p]=0;
		if(s==t){
			val[p]=a[s];
			return ;
		}
		int mid=s+((t-s)>>1);
		init(s,mid,p<<1);
		init(mid+1,t,p<<1|1);
		val[p]=(val[ls]+val[rs])%pp;
	}//
	
	void pushdown(int s,int t,int p){
		f[p]=0;
		if(s==t){
			add[p]=0;
			mul[p]=1;
			return ;
		}
		int mid=s+((t-s)>>1);
		val[p<<1]=(val[p<<1]*mul[p]+add[p]*(mid-s+1))%pp;
		val[p<<1|1]=(val[p<<1|1]*mul[p]+add[p]*(t-mid))%pp;
		add[p<<1]=(add[ls]*mul[p]+add[p])%pp;
		add[p<<1|1]=(add[rs]*mul[p]+add[p])%pp;
		mul[p<<1]=mul[ls]*mul[p]%pp;
		mul[p<<1|1]=mul[rs]*mul[p]%pp;
		add[p]=0;
		mul[p]=1;
		f[ls]=f[rs]=1;
		return ;
	}
	
	void Add(int s,int t,int l,int r,int p,ll k){
		if(s>=l&&r>=t){
			val[p]=(val[p]+k*(t-s+1))%pp;
			add[p]=(add[p]+k)%pp;
			f[p]=1;
			return ;
		}
		int mid=s+((t-s)>>1);
		if(f[p])pushdown(s,t,p);
		if(l<=mid)Add(s,mid,l,r,ls,k);
		if(r>mid)Add(mid+1,t,l,r,rs,k);
		val[p]=(val[ls]+val[rs])%pp;	
		return ;
	}
		
	void Mul(int s,int t,int l,int r,int p,ll k){
		if(s>=l&&r>=t){
			val[p]=(val[p]*k)%pp;
			add[p]=add[p]*k%pp;
			mul[p]=mul[p]*k%pp;
			f[p]=1;
			return ;
		}
		int mid=s+((t-s)>>1);
		if(f[p])pushdown(s,t,p);
		if(l<=mid)Mul(s,mid,l,r,ls,k);
		if(r>mid)Mul(mid+1,t,l,r,rs,k);
		val[p]=(val[ls]+val[rs])%pp;	
		return ;
	}//multiply the interval 
	
	ll Sum(int s,int t,int l,int r,int p){
		if(s>=l&&r>=t){
			return val[p];
		}
		int mid=s+((t-s)>>1)%pp;
		ll sum=0;
		if(f[p])pushdown(s,t,p);
		if(l<=mid)sum+=Sum(s,mid,l,r,ls);
		if(r>mid)sum+=Sum(mid+1,t,l,r,rs);
		return sum%pp;
	}//get sum of the interval from l to r 
	
	void print(int s,int t,int p,int l){
		for(int i=0;i<l;i++)printf("\t");
		printf("pos-%d  val-%d  add-%d  mul-%d  f-%d  L-%d  R-%d\n"\
		,p,val[p],add[p],mul[p],f[p],s,t);
		if(s==t)return ;
		int mid=s+((t-s)>>1);
		print(s,mid,ls,l+1);
		print(mid+1,t,rs,l+1); 
	}//print the value of each point , used to debug
}ss;//segment tree

int main(){
	scanf("%d%d%lld",&n,&m,&pp);
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i]);
	}
	ss.init(1,n,1);
	for(int i=1;i<=m;i++){
		int k,x,y;
		ll kk;
		scanf("%d%d%d",&k,&x,&y);
		if(k==2){
			scanf("%lld",&kk);
			ss.Add(1,n,x,y,1,kk);
		} else if(k==1){
			scanf("%lld",&kk);
			ss.Mul(1,n,x,y,1,kk);
		} else if(k==3){
			printf("%lld\n",ss.Sum(1,n,x,y,1));
		}
		/* 
		ss.print(1,n,1,0);
		puts("");
		puts("");
		*/
	}
}

/*

5 5 100
1 2 3 4 5 
1 1 5 2
2 1 5 2
1 1 4 2
2 2 5 2
3 2 4 

8 10 571373
1 1 1 1 1 1 1 1 
2 4 8 2
1 2 8 2
2 2 6 2
2 5 8 2

3 2 8
1 1 5 2
3 1 5
1 5 8 2
2 5 8 2
2 5 8 2

*/

